package com.xplay.xpocker.socket;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xplay.xpocker.entity.mahjong.MahjongRoomBuilder;
import com.xplay.xpocker.meta.realize.MahjongRoomEntity;
import com.xplay.xpocker.entity.mahjong.MahjongUserTask;
import com.xplay.xpocker.meta.MessageContent;
import com.xplay.xpocker.meta.realize.MahjongUserChannel;
import com.xplay.xpocker.observer.SubscriptionSubject;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static com.xplay.xpocker.util.DictionaryConst.MahjongAction.*;

/**
 * @author wanjie
 * @date 2021/3/17 20:11
 */


public interface UserChannelMate {
    // 所有在线用户的通道 ----- 这个map 用户离线了一定要维护

    public static final Logger log = LoggerFactory.getLogger(UserChannelMate.class);

    public static ConcurrentHashMap<String, SubscriptionSubject> diskPart = new ConcurrentHashMap<>();


    public static final String ROOM_TYPE_KEY  = "roomType";

    public static final String ROOM_CODE_KEY  = "roomCode";

    public static final String USER_CHANNEL_KEY = "userId";

    public default String getUserId(ChannelHandlerContext ctx) {
        try {
            return ctx.channel().attr(AttributeKey.valueOf(USER_CHANNEL_KEY)).toString();
        } catch (Exception e) {
            return "default";
        }
    }

    public default String getRoomCode(ChannelHandlerContext ctx) {
        return ctx.channel().attr(AttributeKey.valueOf("roomCode")).toString();
    }

    /**
     * 提示用户执行操作
     *
     * @param roomInfo
     * @param userId
     */

    public default void promptUserDoAction(MahjongRoomEntity roomInfo, String userId) {
        senMessage(getCtxByUserId(roomInfo.getCode(), userId), new MessageContent<MahjongUserTask>(roomInfo.getUserTask(userId), ACTION_TIPS));
    }

    /**
     * 不管用户在线与否 都将消息发给用户
     * 房间内 统一 消息发送地方......
     *
     * @param ctx
     * @param obj
     */

    public default void senMessage(ChannelHandlerContext ctx, MessageContent obj) {
        try {
            if (null != ctx && ctx.channel().isOpen()) {
                String data = new ObjectMapper().writeValueAsString(obj);
                ctx.channel().writeAndFlush(new TextWebSocketFrame(data));
                log.info(String.format("------------message send success,user online[%s]-------msg[%s]----", obj.getUserId(), data));
            } else {
                log.error(String.format("------------message send error,user not online[%s]-----------", obj.getUserId()));
            }
        } catch (Exception e) {
            log.info("------------message send error,user not online[%s]-----------", obj.getUserId());
            e.printStackTrace();
        }

    }


    /**
     * 通知所有玩家刷新房间信息....
     *
     * @param
     * @param roomInfo
     */

    public default void updateRoomInfo(MahjongRoomEntity roomInfo) {
        try {
            HashMap<String, MahjongUserChannel> allUserInfo = roomInfo.getAllUserInfo();
            for (Map.Entry<String, MahjongUserChannel> entry : allUserInfo.entrySet()) {
                senMessage(getCtxByUserId(roomInfo.getCode(), entry.getKey()), new MessageContent(MahjongRoomBuilder.inGame(roomInfo, entry.getValue()), READ_HOME));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public default ChannelHandlerContext getCtxByUserId(String roomCode, String userId) {
        try {
            return diskPart.get(roomCode).getUserChannelByUserId(userId);
        } catch (Exception e) {
            log.error(String.format("The user did not join the subscription object======[%s]", userId));
            e.printStackTrace();
        }
        return null;
    }

}
